出处:掘金
原作者:ErpanOmer
在前端性能优化中,Total Blocking Time (TBT) 是一个不容忽视的重要指标。它是衡量网页交互性能的关键指标之一,尤其对单页应用和动态内容页面尤为重要。本文将通过理论解析、代码示例以及优化策略,为您全面剖析 TBT 的本质和优化方法
Total Blocking Time 表示从页面首次开始渲染内容到用户可交互之间,被阻塞时间的总和。具体来说,它计算的是长任务(任务执行时间超过 50 ms)阻塞主线程的时间
核心概念:
公式:
TBT = ∑(每个任务耗时 - 50ms) # 仅计算超过 50ms 的任务
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.duration > 50) {
console.log(`Long Task Detected: ${entry.duration}ms`);
}
}
});
observer.observe({ type: 'longtask', buffered: true });
问题:JavaScript 阻塞主线程,导致用户无法进行操作
示例:
// 一个耗时过长的同步任务
function heavyTask() {
const start = Date.now();
while (Date.now() - start < 200) {
// 模拟长任务
}
}
heavyTask();
优化方法:将长任务拆分为小任务,通过 setTimeout 或 requestIdleCallback 优化
function heavyTaskOptimized() {
let start = 0;
const chunk = 20; // 每次处理 20ms
function processChunk() {
const now = Date.now();
while (Date.now() - now < chunk) {
// 模拟部分任务
start++;
}
if (start < 1000) {
setTimeout(processChunk, 0); // 将剩余任务推迟到下一个事件循环
}
}
processChunk();
}
heavyTaskOptimized();
问题:频繁的 DOM 操作占用主线程
示例:
// 创建 1000 个 DOM 元素
for (let i = 0; i < 1000; i++) {
const div = document.createElement('div');
div.textContent = `Element ${i}`;
document.body.appendChild(div);
}
优化方法:使用 DocumentFragment 或虚拟 DOM 减少渲染阻塞
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
const div = document.createElement('div');
div.textContent = `Element ${i}`;
fragment.appendChild(div);
}
document.body.appendChild(fragment);
问题:复杂的 CSS 样式或动画阻塞渲染
示例:
.heavy-animation {
animation: heavyTask 10s linear infinite;
}
@keyframes heavyTask {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
优化方法:尽量使用 transform 和 opacity,避免触发布局和重绘
.optimized-animation {
animation: optimizedTask 10s linear infinite;
}
@keyframes optimizedTask {
0% { transform: translateX(0); }
100% { transform: translateX(100px); }
}
requestIdleCallback 或 Web Workers 来异步执行任务import() 延迟加载非关键 JavaScript 模块import('./heavy-module.js').then(module => { module.init(); });transform 和 opacity,避免触发重排和重绘import { Perfume } from 'perfume.js';
const perfume = new Perfume({ firstPaint: true, timeToInteractive: true });
console.log(`TBT: ${perfume.totalBlockingTime}`);
TBT 是一个反映网页交互性能的重要指标,它不仅影响用户体验,还影响 SEO 和核心 Web 指标的评分。在现代 Web 开发中,通过优化 JavaScript 执行、减少阻塞操作和充分利用异步技术,可以显著降低 TBT 提升性能
优化 TBT 的过程,既是对技术能力的考验,也是提升用户体验的关键一步。无论是小型项目还是复杂应用,专注于优化 TBT,都会为用户带来更流畅的使用体验